# -*- coding: utf-8 -*-
from loguru import logger
from webrunnercore import wr #wr模块是webrunner内置的脚本增强sdk
from webrunnercore import *



class 测试负载(WebLoadMachine):
    '''
    用户自定义负载信息
    '''
    负载名称 = '默认负载'

    测试机 = [
        {
            "ip地址": '127.0.0.1',
            "端口": 50000,
            "节点数": 1,
            "主节点": True
        },
    ]

class 测试场景(WebScenario):
    '''
    用户自定义场景信息
    '''
    场景名称 = '默认场景'

    模式 = '梯形负载'
    参数 = {
        '用户数': 100,
        '创建速率': 10,
        '运行时长': 60
    }



class Transaction_Morenfenzu(SerialTransaction):
    '''
    事务定义, 一个事务由多个task构成, 每个task只包含一个请求
    '''

    def __init__(self, parent: "User") -> None:
        super().__init__(parent)
        # 添加实例变量来存储动态获取的课程ID
        self.dynamic_course_id = None
        # 存储动态token
        self.token = None

    @property
    def transaction(self):
        # 事务名称
        return "morenfenzu"

    def on_start(self):
        # 事务启动函数
        super().on_start()
    
    @task
    def task_0(self):
        url = "http://localhost:8080/api/user/login"
        headers = {'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Content-Length': '40', 'Content-Type': 'application/json', 'Host': 'localhost:8080', 'Origin': 'http://localhost:8080', 'Referer': 'http://localhost:8080/login', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"'}
        params = {}
        # application/json (dict)
        data = {}
        data['userName'] = 'admin'
        data['password'] = '123456'

        res = self.post(url, headers=headers, params=params, json=data)
        # 从登录响应中提取token并存储
        if res.status_code == 200:
            try:
                response_data = res.json()
                if 'data' in response_data and 'token' in response_data['data']:
                    self.token = response_data['data']['token']
                    logger.info("登录成功，获取到token")
                else:
                    logger.warning("登录响应中没有找到token")
            except Exception as e:
                logger.error(f"解析登录响应失败: {e}")
        # application/json,res.json()

    
    @task
    def task_1(self):
        url = "http://localhost:8080/api/course/add"
        headers = {'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Host': 'localhost:8080', 'Origin': 'http://localhost:8080', 'Referer': 'http://localhost:8080/course', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"'}
        
        # 如果有token，添加到headers中
        if self.token:
            headers['token'] = self.token
            logger.info(f"使用token: {self.token[:20]}...")
        else:
            logger.warning("没有token，可能影响新增课程操作")
            
        params = {}
        params['currentUserId']='1'
        
        # 生成唯一的课程名称，避免重复
        import uuid
        unique_course_name = f'test_{uuid.uuid4().hex[:8]}'
        
        # application/json (dict)
        data = {}
        data['courseId'] = None
        data['courseName'] = unique_course_name
        data['courseIntro'] = f'测试课程简介_{unique_course_name}'
        data['courseCover'] = 'tv.jpg'
        data['courseSort'] = 1
        data['courseVideo'] = '1.mp4'
        data['courseAuthor'] = 'test'
        data['createPersonId'] = 1

        logger.info(f"准备新增课程: {unique_course_name}")
        logger.info(f"请求数据: {data}")
        
        res = self.post(url, headers=headers, params=params, json=data)
        
        # 保存新增课程返回的ID
        logger.info(f"新增课程响应状态码: {res.status_code}")
        logger.info(f"新增课程响应头: {dict(res.headers)}")
        
        if res.status_code == 200:
            try:
                response_data = res.json()
                logger.info(f"新增课程完整响应: {response_data}")
                
                # 检查新增是否成功
                if response_data.get('code') == 200 and response_data.get('message') == '新增课程成功':
                    logger.info("新增课程成功，现在通过查询获取课程ID")
                    
                    # 新增成功后，通过查询接口获取刚创建的课程ID
                    self._get_course_id_by_name(unique_course_name, headers)
                else:
                    logger.error(f"新增课程失败: {response_data}")
                    
            except Exception as e:
                logger.error(f"解析新增课程响应失败: {e}")
                logger.error(f"原始响应内容: {res.text}")
        else:
            logger.error(f"新增课程失败，状态码: {res.status_code}")
            logger.error(f"错误响应内容: {res.text}")
        # application/json,res.json()

    def _get_course_id_by_name(self, course_name, headers):
        """通过课程名称查询获取课程ID"""
        try:
            url = "http://localhost:8080/api/course/list-page"
            params = {
                'current': '1',
                'courseName': course_name,
                'currentUserId': '1'
            }
            
            logger.info(f"查询课程: {course_name}")
            res = self.get(url, headers=headers, params=params)
            
            if res.status_code == 200:
                response_data = res.json()
                logger.info(f"查询课程响应: {response_data}")
                
                if response_data.get('code') == 200 and 'data' in response_data:
                    course_list = response_data['data'].get('records', [])
                    if course_list:
                        # 找到匹配的课程
                        for course in course_list:
                            if course.get('courseName') == course_name:
                                self.dynamic_course_id = course.get('courseId')
                                logger.info(f"找到课程ID: {self.dynamic_course_id}")
                                return
                        
                        logger.warning(f"未找到课程名称匹配的记录: {course_name}")
                    else:
                        logger.warning("课程列表为空")
                else:
                    logger.error(f"查询课程失败: {response_data}")
            else:
                logger.error(f"查询课程失败，状态码: {res.status_code}")
                
        except Exception as e:
            logger.error(f"查询课程ID时发生错误: {e}")

    
    @task
    def task_2(self):
        # 检查是否有动态获取的课程ID
        if self.dynamic_course_id is None:
            logger.warning("没有可用的课程ID，跳过查询操作")
            return
            
        url = "http://localhost:8080/api/course/list-page"
        headers = {'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Host': 'localhost:8080', 'Referer': 'http://localhost:8080/course', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"'}
        
        # 如果有token，添加到headers中
        if self.token:
            headers['token'] = self.token
            
        params = {}
        params['current']='1'
        params['courseName']='test'
        params['currentUserId']='1'
        # null
        data = None
        res = self.get(url, headers=headers, params=params, data=data)
        logger.info(f"查询课程列表，当前课程ID: {self.dynamic_course_id}")
        # application/json,res.json()

    
    @task
    def task_3(self):
        # 检查是否有动态获取的课程ID
        if self.dynamic_course_id is None:
            logger.warning("没有可用的课程ID，跳过更新操作")
            return
            
        url = "http://localhost:8080/api/course/update/true"
        headers = {'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Host': 'localhost:8080', 'Origin': 'http://localhost:8080', 'Referer': 'http://localhost:8080/course', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"'}
        
        # 如果有token，添加到headers中
        if self.token:
            headers['token'] = self.token
            
        params = {}
        # application/json (dict)
        data = {}
        data['courseId'] = self.dynamic_course_id  # 使用动态获取的课程ID
        data['courseName'] = f'test1_{self.dynamic_course_id}'  # 标题包含ID便于识别
        data['courseIntro'] = f'更新后的课程简介_{self.dynamic_course_id}'
        data['courseCover'] = 'tv.jpg'
        data['courseSort'] = 1
        data['courseVideo'] = '1.mp4'
        data['courseAuthor'] = 'test'
        data['createPersonId'] = 1
        data['courseStatus'] = 1
        data['createTime'] = '2025-07-05T15:10:07'
        data['updateTime'] = '2025-07-05T15:10:07'

        res = self.put(url, headers=headers, params=params, json=data)
        logger.info(f"更新课程ID: {self.dynamic_course_id}")
        # application/json,res.json()

    
    @task
    def task_4(self):
        # 检查是否有动态获取的课程ID
        if self.dynamic_course_id is None:
            logger.warning("没有可用的课程ID，跳过删除操作")
            return
            
        url = "http://localhost:8080/api/course/delete"
        headers = {'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Host': 'localhost:8080', 'Origin': 'http://localhost:8080', 'Referer': 'http://localhost:8080/course', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"'}
        
        # 如果有token，添加到headers中
        if self.token:
            headers['token'] = self.token
            
        params = {}
        params['courseId'] = str(self.dynamic_course_id)  # 使用动态获取的课程ID
        # null
        data = None
        res = self.delete(url, headers=headers, params=params, data=data)
        logger.info(f"删除课程ID: {self.dynamic_course_id}")
        # application/json,res.json()


    def on_stop(self):
        # 事务结束函数
        super().on_stop()


class WebrunnerAction(BrowserAction):
    '''
    事务集合, 一个Action包含多个Transaction事务, @task装饰器参数表示事务混合比，
    初始化事务 和 结束事务只执行一次， 执行事务按照混合比执行多次
    '''
    def __init__(self, parent: "User") -> None:
        super().__init__(parent)

    def on_start(self):
        super().on_start()

    @task(1)
    @transaction("morenfenzu")
    def task_morenfenzu(self):
        # 执行事务
        Transaction_Morenfenzu(self).run()

    def on_stop(self):
        super().on_stop()


class WebrunnerUser(CFastHttpUser):
    '''
    虚拟用户, 一个用户循环执行一个Action
    '''
    host = ""
    tasks = [WebrunnerAction]



    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

    def on_start(self):
        # 所有虚拟用户创建完成后开始执行，主要用于定义参数化和检查点的策略

        super().on_start()